package com.sxj.corejava.code14_Lambda表达式;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test10_终止操作 {
    public static List<Integer> list = Arrays.asList(13, 6, 2, 1, 8, 21, 1, 16, 12, 2);

    public static void main(String[] args) {
//        testAllMatch();
//        testAnyMatch();
//        testNoneMatch();
//        testFindFirst();
//        testFindAny();
//        testCount();
//        testMax();
//        testMin();
//        testReduce();
        testCollect();
    }

    public static void testAllMatch() {
        boolean flag = list.stream()
                // 检查流中所有元素是否都满足指定条件
                // 只要有任意一个不满足,则返回false
                .allMatch(i -> i % 2 == 0);
        System.out.println("流中元素是否全部是偶数:" + flag);

        flag = list.stream()
                .allMatch(i -> i > 0);
        System.out.println("流中元素是否全部正数:" + flag);
    }

    public static void testAnyMatch() {
        boolean flag = list.stream()
                // 检查流中是否存在元素满足指定条件
                // 只要有任意一个满足,则返回true
                .anyMatch(i -> i % 2 == 0);
        System.out.println("流中元素是否包含偶数:" + flag);
    }

    public static void testNoneMatch() {
        boolean flag = list.stream()
                // 检查流中所有元素是否都不满足指定条件
                // 只要有任意一个满足,则返回false
                .noneMatch(i -> i % 2 == 0);
        System.out.println("流中元素是否都不是偶数:" + flag);

        flag = list.stream()
                .noneMatch(i -> i < 0);
        System.out.println("流中元素是否都不是负数:" + flag);
    }

    public static void testFindFirst() {
        list = new ArrayList<>();
        // 此时的方法返回值是一个容器,该容器中存储了返回的数据
        Optional<Integer> first = list.stream()
                .findFirst();
        // 如果容器中存在数据,则直接返回
        // 如果容器中没有数据,会报错
//        System.out.println(first.get());
        // 为了避免抛出异常,在取值时可以先判断是否有元素
        // 判断容器中是否有值
        // 定义一个变量,用于接收容器中的数据
        Integer num;
        if (first.isPresent()) {
            num = first.get();
        } else {
            // 如果没有,可以设置一个默认值
            num = first.orElse(0);
        }
        System.out.println(num);
    }

    public static void testFindAny() {
        Optional<Integer> any = list.stream()
                .findAny();
        Optional<Integer> any2 = list.stream()
                .findAny();
        System.out.println("当前线程:" + any.get());
        System.out.println("当前线程:" + any2.get());

        new Thread() {
            @Override
            public void run() {
                Optional<Integer> any = list.parallelStream().findAny();
                System.out.println("第一个线程:" + any.get());
            }
        }.start();

        new Thread() {
            @Override
            public void run() {
                Optional<Integer> any = list.parallelStream().findAny();
                System.out.println("第二个线程:" + any.get());
            }
        }.start();
    }

    public static void testCount() {
        long count = list.stream().count();
        System.out.println("流中元素的数量:" + count);
    }

    public static void testMax() {
        // 该方法本质上是做了一个升序排序,取最后一个值
        // 升序
        Optional<Integer> max = list.stream().max((o1, o2) -> o1 - o2);
        System.out.println(max.get());
        // 如果使用降序,实际上取到的是最小值
        // 降序
        Optional<Integer> max2 = list.stream().max((o1, o2) -> o2 - o1);
        System.out.println(max2.get());
    }

    public static void testMin() {
        // 与最大值相反
        // 升序
        Optional<Integer> min = list.stream().min((o1, o2) -> o1 - o2);
        System.out.println(min.get());
        // 降序
        Optional<Integer> min2 = list.stream().min((o1, o2) -> o2 - o1);
        System.out.println(min2.get());
    }

    public static void testReduce() {
        // 计算流中所有元素的和
        Optional<Integer> reduce = list.stream().reduce((a, b) -> a + b);
        System.out.println("元素的和为:" + reduce.get());
        // 在Integer中提供了sum方法,实现求和
        // 可以通过方法引用来实现
        Optional<Integer> reduce2 = list.stream().reduce(Integer::sum);
        System.out.println("元素的和为:" + reduce2.get());

        // 可以通过无限流来实现任何数据的求和
        // 计算1-100之和
        // 生成一个无限流,从1开始,每次自增1
        Optional<Integer> reduce3 = Stream.iterate(1, i -> i + 1)
                // 取前100个,即到100为止
                .limit(100)
                // 求和
                .reduce(Integer::sum);
        System.out.println("1-100之间整数之和为:" + reduce3.get());

        // 计算1-100之间奇数之和
        Optional<Integer> reduce4 = Stream.iterate(1, i -> i + 2)
                // 取前100个,即到100为止
                .limit(50)
                // 求和
                .reduce(Integer::sum);
        System.out.println("1-100之间奇数之和为:" + reduce4.get());

        // 计算1-100之间偶数之和
        Optional<Integer> reduce5 = Stream.iterate(2, i -> i + 2)
                // 取前100个,即到100为止
                .limit(50)
                // 求和
                .reduce(Integer::sum);
        System.out.println("1-100之间偶数之和为:" + reduce5.get());
    }

    public static void testCollect() {
        List<Integer> list2 = list.stream()
                .filter(i -> i % 2 == 0)
                .collect(Collectors.toList());
        System.out.println(list2);

        Set<Integer> set = list.stream().collect(Collectors.toSet());
        System.out.println(set);

    }
}
